class Solution {
    public int[] findOrder(int numCourses, int[][] prerequisites) {
        List<List<Integer>> graph = new ArrayList<>(numCourses);
        int[] inDegree = new int[numCourses];
        for (int i = 0; i < numCourses; i++) {
            graph.add(new ArrayList<>());
            inDegree[i] = 0;
        }
        for (int[] prerequisite : prerequisites) {
            int course = prerequisite[0];
            int preCourse = prerequisite[1];
            graph.get(preCourse).add(course);
            inDegree[course]++;
        }
        int[] courseLearned = new int[numCourses];
        int learned = 0;
        Queue<Integer> queue = new LinkedList<>();
        for (int i = 0; i < numCourses; i++) {
            if (inDegree[i] == 0) {
                queue.offer(i);
            }
        }
        while (!queue.isEmpty()) {
            int course = queue.poll();
            courseLearned[learned++] = course;
            for (int nextCourses : graph.get(course)) {
                inDegree[nextCourses]--;
                if (inDegree[nextCourses] == 0) {
                    queue.offer(nextCourses);
                }
            }
        }
        return learned == numCourses ? courseLearned : new int[0];
    }
}
